FullConnection ================= 全连接(矩阵乘融合偏置与激活)。对输入 ``A`` 与权重 ``B`` 做矩阵乘,可选叠加 ``bias``,再按 ``activation_type`` 做逐元素激活,结果写入 ``C``。 设有效乘积矩阵为 :math:`A_{\mathrm{eff}}`、:math:`B_{\mathrm{eff}}`,形状分别为 :math:`M \times K` 与 :math:`K \times N`,则: .. math:: C_{i,j} = \operatorname{act}\!\left( \sum_{k=0}^{K-1} (A_{\mathrm{eff}})_{i,k}\,(B_{\mathrm{eff}})_{k,j} + b_{i,j} \right) 转置约定(行优先存储;由 ``params`` 中 ``A_transpose``、``B_transpose`` 控制,取值 0 或 1): - ``A_transpose = 0``:``A`` 形状 :math:`M \times K`,:math:`(A_{\mathrm{eff}})_{i,k} = A_{i\cdot K+k}` - ``A_transpose = 1``:``A`` 形状 :math:`K \times M`,:math:`(A_{\mathrm{eff}})_{i,k} = A_{k\cdot M+i}` - ``B_transpose = 0``:``B`` 形状 :math:`K \times N`,:math:`(B_{\mathrm{eff}})_{k,j} = B_{k\cdot N+j}` - ``B_transpose = 1``:``B`` 形状 :math:`N \times K`,:math:`(B_{\mathrm{eff}})_{k,j} = B_{j\cdot K+k}` 偏置(``bias`` 为 ``NULL`` 时 :math:`b_{i,j} = 0`): - ``bias_broadcast = 0``:``bias`` 形状 :math:`M \times N`,:math:`b_{i,j} = \mathrm{bias}_{i\cdot N+j}` - ``bias_broadcast = 1``:``bias`` 形状 :math:`N`,沿行广播,:math:`b_{i,j} = \mathrm{bias}_{j}` 激活(``activation_type``): - ``0``:恒等,:math:`\operatorname{act}(x)=x` - ``1``:ReLU,:math:`\operatorname{act}(x)=\max(0,x)` - ``2``:ReLU6,:math:`\operatorname{act}(x)=\min(\max(0,x), 6)` 输入: - **A** - 输入矩阵地址 - **B** - 权重矩阵地址 - **bias** - 偏置地址;无偏置时传 ``NULL`` - **params** - ``long long`` 参数数组,长度至少 7,布局见下 - **core_mask** - 核掩码(仅共享存储版本使用) params 布局: - ``[0]`` ``M`` - 输出行数 - ``[1]`` ``N`` - 输出列数 - ``[2]`` ``K`` - 归约维长度 - ``[3]`` ``activation_type`` - 激活类型,取值 ``{0,1,2}`` - ``[4]`` ``A_transpose`` - 是否按转置语义读 ``A``,取值 ``{0,1}`` - ``[5]`` ``B_transpose`` - 是否按转置语义读 ``B``,取值 ``{0,1}`` - ``[6]`` ``bias_broadcast`` - 偏置是否按列广播,取值 ``{0,1}`` 输出: - **C** - 输出矩阵地址,形状 :math:`M \times N` 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持 int8、fp32 - MT7004 支持 fp16、fp32 - 本 DSP 接口的激活枚举为 ``0/1/2``(NONE / ReLU / ReLU6),与 schema ``ActivationType`` 数值不完全相同 **共享存储版本:** .. c:function:: void i8_full_connection_s(int8_t *A, int8_t *B, int8_t *C, int8_t *bias, long long *params, int core_mask) .. c:function:: void hp_full_connection_s(float16 *A, float16 *B, float16 *C, float16 *bias, long long *params, int core_mask) .. c:function:: void fp_full_connection_s(float *A, float *B, float *C, float *bias, long long *params, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 18 // MT7004 示例(共享存储多核,DDR 地址) void TestFullConnectionSMCFp32(int core_mask) { int core_id = get_core_id(); int logic_core_id = GetLogicCoreId(core_mask, core_id); int core_num = GetCoreNum(core_mask); float *A = (float *)0x81000000; float *B = (float *)0x82000000; float *C = (float *)0x85000000; long long params[7]; params[0] = 16; // M params[1] = 16; // N params[2] = 16; // K params[3] = 1; // ACTIVATION_RELU params[4] = 0; // A_transpose params[5] = 0; // B_transpose params[6] = 1; // bias_broadcast sys_bar(0, core_num); fp_full_connection_s(A, B, C, NULL, params, core_mask); } void main() { int core_mask = 0b1111; TestFullConnectionSMCFp32(core_mask); } **私有存储版本:** .. c:function:: void i8_full_connection_p(int8_t *A, int8_t *B, int8_t *C, int8_t *bias, long long *params) .. c:function:: void hp_full_connection_p(float16 *A, float16 *B, float16 *C, float16 *bias, long long *params) .. c:function:: void fp_full_connection_p(float *A, float *B, float *C, float *bias, long long *params) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 14 // MT7004 示例(私有存储单核,AM 地址) void TestFullConnectionAMFp32(void) { float *A = (float *)0x10010000; float *B = (float *)0x10020000; float *C = (float *)0x10050000; long long params[7]; params[0] = 16; // M params[1] = 16; // N params[2] = 16; // K params[3] = 1; // ACTIVATION_RELU params[4] = 0; // A_transpose params[5] = 0; // B_transpose params[6] = 1; // bias_broadcast fp_full_connection_p(A, B, C, NULL, params); } void main() { TestFullConnectionAMFp32(); }